//
//  NSDate+WN.m
//  Whatnet_iOS
//
//  Created by 北辰 on 2019/5/20.
//  Copyright © 2019 什么网络. All rights reserved.
//

#import "NSDate+WN.h"
static const NSCalendarUnit unitFlags = (NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitWeekOfMonth |  NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond | NSCalendarUnitWeekday | NSCalendarUnitWeekdayOrdinal);

@implementation NSDate (WN)

#pragma mark - 获取日历单例对象
+ (NSCalendar *)calendar {
    static NSCalendar *sharedCalendar = nil;
    if (!sharedCalendar) {
        // 创建日历对象：返回当前客户端的逻辑日历(当每次修改系统日历设定，其实例化的对象也会随之改变)
        sharedCalendar = [NSCalendar autoupdatingCurrentCalendar];
    }
    return sharedCalendar;
}

#pragma mark - 获取指定日期的年份
- (NSInteger)wn_year {
    // NSDateComponent 可以获得日期的详细信息，即日期的组成
    NSDateComponents *components = [[NSDate calendar] components:unitFlags fromDate:self];
    return components.year;
}

#pragma mark - 获取指定日期的月份
- (NSInteger)wn_month {
    NSDateComponents *components = [[NSDate calendar] components:unitFlags fromDate:self];
    return components.month;
}

#pragma mark - 获取指定日期的天
- (NSInteger)wn_day {
    NSDateComponents *components = [[NSDate calendar] components:unitFlags fromDate:self];
    return components.day;
}

#pragma mark - 获取指定日期的小时
- (NSInteger)wn_hour {
    NSDateComponents *components = [[NSDate calendar] components:unitFlags fromDate:self];
    return components.hour;
}

#pragma mark - 获取指定日期的分钟
- (NSInteger)wn_minute {
    NSDateComponents *comps = [[NSDate calendar] components:unitFlags fromDate:self];
    return comps.minute;
}

#pragma mark - 获取指定日期的秒
- (NSInteger)wn_second {
    NSDateComponents *components = [[NSDate calendar] components:unitFlags fromDate:self];
    return components.second;
}

#pragma mark - 获取指定日期的星期
- (NSInteger)wn_weekday {
    NSDateComponents *components = [[NSDate calendar] components:unitFlags fromDate:self];
    return components.weekday;
}

///// 提示：除了使用 NSDateComponents 获取年月日等信息，还可以通过格式化日期获取日期的详细的信息 //////

#pragma mark - 创建date
+ (NSDate *)wn_setYear:(NSInteger)year month:(NSInteger)month day:(NSInteger)day hour:(NSInteger)hour minute:(NSInteger)minute second:(NSInteger)second {
    NSCalendar *calendar = [NSDate calendar];
    // 初始化日期组件
    NSDateComponents *components = [calendar components:unitFlags fromDate:[NSDate date]];
    if (year >= 0) {
        components.year = year;
    }
    if (month >= 0) {
        components.month = month;
    }
    if (day >= 0) {
        components.day = day;
    }
    if (hour >= 0) {
        components.hour = hour;
    }
    if (minute >= 0) {
        components.minute = minute;
    }
    if (second >= 0) {
        components.second = second;
    }
    NSDate *date = [calendar dateFromComponents:components];
    return date;
}

+ (NSDate *)wn_setYear:(NSInteger)year month:(NSInteger)month day:(NSInteger)day hour:(NSInteger)hour minute:(NSInteger)minute {
    return [self wn_setYear:year month:month day:day hour:hour minute:minute second:-1];
}

+ (NSDate *)wn_setYear:(NSInteger)year month:(NSInteger)month day:(NSInteger)day {
    return [self wn_setYear:year month:month day:day hour:-1 minute:-1 second:-1];
}

+ (NSDate *)wn_setYear:(NSInteger)year month:(NSInteger)month {
    return [self wn_setYear:year month:month day:-1 hour:-1 minute:-1 second:-1];
}

+ (NSDate *)wn_setYear:(NSInteger)year {
    return [self wn_setYear:year month:-1 day:-1 hour:-1 minute:-1 second:-1];
}

+ (NSDate *)wn_setMonth:(NSInteger)month day:(NSInteger)day hour:(NSInteger)hour minute:(NSInteger)minute {
    return [self wn_setYear:-1 month:month day:day hour:hour minute:minute second:-1];
}

+ (NSDate *)wn_setMonth:(NSInteger)month day:(NSInteger)day {
    return [self wn_setYear:-1 month:month day:day hour:-1 minute:-1 second:-1];
}

+ (NSDate *)wn_setHour:(NSInteger)hour minute:(NSInteger)minute {
    return [self wn_setYear:-1 month:-1 day:-1 hour:hour minute:minute second:-1];
}


+ (NSDate *)setYear:(NSInteger)year {
    return [self wn_setYear:year];
}

+ (NSDate *)setYear:(NSInteger)year month:(NSInteger)month {
    return [self wn_setYear:year month:month];
}

+ (NSDate *)setYear:(NSInteger)year month:(NSInteger)month day:(NSInteger)day {
    return [self wn_setYear:year month:month day:day];
}

+ (NSDate *)setYear:(NSInteger)year month:(NSInteger)month day:(NSInteger)day hour:(NSInteger)hour minute:(NSInteger)minute {
    return [self wn_setYear:year month:month day:day hour:hour minute:minute];
}

+ (NSDate *)setMonth:(NSInteger)month day:(NSInteger)day hour:(NSInteger)hour minute:(NSInteger)minute {
    return [self wn_setMonth:month day:day hour:hour minute:minute];
}

+ (NSDate *)setMonth:(NSInteger)month day:(NSInteger)day {
    return [self wn_setMonth:month day:day];
}

+ (NSDate *)setHour:(NSInteger)hour minute:(NSInteger)minute {
    return [self wn_setHour:hour minute:minute];
}


//获取自1970以来的毫秒
+ (NSString *)wn_getmillSecoundForm1070:(NSDate *)date{
    NSTimeInterval nowtime = [date timeIntervalSince1970]*1000;
    long long theTime = [[NSNumber numberWithDouble:nowtime] longLongValue];
    return [@(theTime) stringValue];
}

#pragma mark - 日期和字符串之间的转换：NSDate --> NSString
+ (NSString *)wn_getDateString:(NSDate *)date format:(NSString *)format {
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    dateFormatter.locale = [NSLocale currentLocale];
    dateFormatter.timeZone = [NSTimeZone localTimeZone];
    dateFormatter.dateFormat = format;
    NSString *destDateString = [dateFormatter stringFromDate:date];
    
    return destDateString;
}

#pragma mark - 包含星期几 日期和字符串之间的转换：NSDate --> NSString yyyy-mm-dd week HH:MM
+ (NSString *)wn_getDateWeekString:(NSDate *)date{
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    dateFormatter.locale = [NSLocale currentLocale];
    dateFormatter.timeZone = [NSTimeZone localTimeZone];
    dateFormatter.dateFormat = @"yyyy-MM-dd HH:mm";
    NSString *destDateString = [dateFormatter stringFromDate:date];
    NSString * week = [self weekWithIndex:[date wn_weekday]];
    return [destDateString stringByReplacingOccurrencesOfString:@" " withString:week];
}


#pragma mark - 日期和字符串之间的转换：NSString --> NSDate
+ (NSDate *)wn_getDate:(NSString *)dateString format:(NSString *)format {
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
    dateFormatter.locale = [NSLocale currentLocale];
    dateFormatter.timeZone = [NSTimeZone localTimeZone];
    dateFormatter.dateFormat = format;
    NSDate *destDate = [dateFormatter dateFromString:dateString];
    
    return destDate;
}

#pragma mark - 算法1：获取某个月的天数（通过年月求每月天数）
+ (NSUInteger)wn_getDaysInYear:(NSInteger)year month:(NSInteger)month {
    BOOL isLeapYear = year % 4 == 0 ? (year % 100 == 0 ? (year % 400 == 0 ? YES : NO) : YES) : NO;
    switch (month) {
        case 1:case 3:case 5:case 7:case 8:case 10:case 12:
        {
            return 31;
            break;
        }
        case 4:case 6:case 9:case 11:
        {
            return 30;
            break;
        }
        case 2:
        {
            if (isLeapYear) {
                return 29;
                break;
            } else {
                return 28;
                break;
            }
        }
        default:
            break;
    }
    return 0;
}

#pragma mark - 算法2：获取某个月的天数（通过年月求每月天数）
+ (NSUInteger)wn_getDaysInYear2:(NSInteger)year month:(NSInteger)month {
    NSDate *date = [NSDate wn_getDate:[NSString stringWithFormat:@"%@-%@", @(year), @(month)] format:@"yyyy-MM"];
    // 指定日历的算法(这里按公历)
    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    // 只要给个时间给日历,就会帮你计算出来。
    NSRange range = [calendar rangeOfUnit:NSCalendarUnitDay inUnit: NSCalendarUnitMonth forDate:date];
    return range.length;
}

#pragma mark - 获取 日期加上/减去某天数后的新日期
- (NSDate *)wn_addDays:(NSTimeInterval)days {
    // days 为正数时，表示几天之后的日期；负数表示几天之前的日期
    return [self dateByAddingTimeInterval:60 * 60 * 24 * days];
}

#pragma mark - 比较两个时间大小（可以指定比较级数，即按指定格式进行比较）
- (NSComparisonResult)wn_compare:(NSDate *)targetDate format:(NSString *)format {
    NSString *dateString1 = [NSDate wn_getDateString:self format:format];
    NSString *dateString2 = [NSDate wn_getDateString:targetDate format:format];
    NSDate *date1 = [NSDate wn_getDate:dateString1 format:format];
    NSDate *date2 = [NSDate wn_getDate:dateString2 format:format];
    if ([date1 compare:date2] == NSOrderedDescending) {
        return 1;
    } else if ([date1 compare:date2] == NSOrderedAscending) {
        return -1;
    } else {
        return 0;
    }
}

+ (NSString *)weekWithIndex:(NSInteger)index{
    NSString *weekDay;
    switch (index) {
        case 1:
            weekDay = @" 周日 ";
            break;
        case 2:
            weekDay = @" 周一 ";
            break;
        case 3:
            weekDay = @" 周二 ";
            break;
        case 4:
            weekDay = @" 周三 ";
            break;
        case 5:
            weekDay = @" 周四 ";
            break;
        case 6:
            weekDay = @" 周五 ";
            break;
        case 7:
            weekDay = @" 周六 ";
            break;
            
        default:
            break;
    }
    return weekDay;
}

/**
 *  根据毫秒时间戳获取年龄
 */
+ (NSInteger)wn_getAgeWithMillisecondM:(long long)millisecond{
    NSTimeInterval second = millisecond / 1000;
    NSDate *date = [NSDate dateWithTimeIntervalSince1970:second];
    return [self wn_getAgeWithDate:date];
}
/**
 *  根据date获取年龄
 */
+ (NSInteger)wn_getAgeWithDate:(NSDate *)date{
    //计算年龄
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
    [dateFormatter setDateFormat:@"yyyy-MM-dd"];
    //当前时间
    NSString *currentDateStr = [dateFormatter stringFromDate:[NSDate date]];
    NSDate *currentDate = [dateFormatter dateFromString:currentDateStr];
    NSTimeInterval time = [currentDate timeIntervalSinceDate:date];
    NSInteger age = ((NSInteger)time)/(3600*24*365);
    return age;
}



+ (NSString *)formatTime:(NSTimeInterval)timeInterval {
    NSDate *date = [NSDate dateWithTimeIntervalSince1970:timeInterval];
    NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
    if ([date isToday]) {
        if([date isJustNow]) {
            return @"刚刚";
        }else {
            formatter.dateFormat = @"HH:mm";
            return [formatter stringFromDate:date];
        }
    }else{
        if ([date isYesterday]) {
            formatter.dateFormat = @"昨天HH:mm";
            return [formatter stringFromDate:date];
        }else if ([date isCurrentWeek]){
            formatter.dateFormat = [NSString stringWithFormat:@"%@%@",[date dateToWeekday],@"HH:mm"];
            return [formatter stringFromDate:date];
        }else{
            if([date isCurrentYear]) {
                formatter.dateFormat = @"MM-dd  HH:mm";
            }else {
                formatter.dateFormat = @"yy-MM-dd  HH:mm";
            }
            return [formatter stringFromDate:date];
        }
    }
    return nil;
}


//时间戳转事件
+ (NSString *)getTimestring:(NSTimeInterval)timeInterval format:(NSString *)format{

    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateStyle:NSDateFormatterMediumStyle];
    [formatter setTimeStyle:NSDateFormatterShortStyle];
    [formatter setDateFormat:format];//@"YYYY-MM-dd HH:mm:ss"
    //设置时区
    NSTimeZone* timeZone = [NSTimeZone timeZoneWithName:@"Asia/Beijing"];
    [formatter setTimeZone:timeZone];
    
    NSDate *date=[NSDate dateWithTimeIntervalSince1970:timeInterval];
    NSString *timeStr=[formatter stringFromDate:date];
    
    
    return timeStr;

}

- (BOOL)isJustNow {
    NSTimeInterval now = [[NSDate new] timeIntervalSince1970];
    return fabs(now - self.timeIntervalSince1970) < 60 * 2 ? YES : NO;
}

- (BOOL)isCurrentWeek {
    NSDate *nowDate = [[NSDate date] dateFormatYMD];
    NSDate *selfDate = [self dateFormatYMD];
    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSDateComponents *cmps = [calendar components:NSCalendarUnitDay fromDate:selfDate toDate:nowDate options:0];
    return cmps.day <= 7;
}

- (BOOL)isCurrentYear {
    NSCalendar *calendar = [NSCalendar currentCalendar];
    int unit = NSCalendarUnitWeekday | NSCalendarUnitMonth | NSCalendarUnitYear;
    NSDateComponents *nowComponents = [calendar components:unit fromDate:[NSDate date]];
    NSDateComponents *selfComponents = [calendar components:unit fromDate:self];
    return selfComponents.year == nowComponents.year;
}

- (NSString *)dateToWeekday {
    NSArray *weekdays = [NSArray arrayWithObjects: @"", @"周日", @"周一", @"周二", @"周三", @"周四", @"周五", @"周六", nil];
    NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
    NSTimeZone *timeZone = [[NSTimeZone alloc] initWithName:@"Asia/Shanghai"];
    [calendar setTimeZone: timeZone];
    NSCalendarUnit calendarUnit = NSCalendarUnitWeekday;
    NSDateComponents *theComponents = [calendar components:calendarUnit fromDate:self];
    return [weekdays objectAtIndex:theComponents.weekday];
}

- (BOOL)isToday {
    NSCalendar *calendar = [NSCalendar currentCalendar];
    int unit = NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear ;
    NSDateComponents *nowComponents = [calendar components:unit fromDate:[NSDate date]];
    NSDateComponents *selfComponents = [calendar components:unit fromDate:self];
    return (selfComponents.year == nowComponents.year) && (selfComponents.month == nowComponents.month) && (selfComponents.day == nowComponents.day);
}

- (BOOL)isYesterday {
    NSDate *nowDate = [[NSDate date] dateFormatYMD];
    NSDate *selfDate = [self dateFormatYMD];
    NSCalendar *calendar = [NSCalendar currentCalendar];
    NSDateComponents *cmps = [calendar components:NSCalendarUnitDay fromDate:selfDate toDate:nowDate options:0];
    return cmps.day == 1;
}

- (NSDate *)dateFormatYMD {
    NSDateFormatter *fmt = [[NSDateFormatter alloc] init];
    fmt.dateFormat = @"yyyy-MM-dd";
    NSString *selfStr = [fmt stringFromDate:self];
    return [fmt dateFromString:selfStr];
}

+(NSString *)getNowTimeTimestamp{
    
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init] ;
    
    [formatter setDateStyle:NSDateFormatterMediumStyle];
    
    [formatter setTimeStyle:NSDateFormatterShortStyle];
    
    [formatter setDateFormat:@"YYYY-MM-dd HH:mm:ss"]; // ----------设置你想要的格式,hh与HH的区别:分别表示12小时制,24小时制
    
    //设置时区,这个对于时间的处理有时很重要
    
    NSTimeZone* timeZone = [NSTimeZone timeZoneWithName:@"Asia/Shanghai"];
    
    [formatter setTimeZone:timeZone];
    
    NSDate *datenow = [NSDate date];//现在时间,你可以输出来看下是什么格式
    
    NSString *timeSp = [NSString stringWithFormat:@"%ld", (long)[datenow timeIntervalSince1970]];
    
    return timeSp;
    
}



+ (NSTimeInterval)pleaseInsertStarTime:(NSDate *)startDate andInsertEndTime:(NSDate *)endDate{

    NSTimeInterval time = [endDate timeIntervalSinceDate:startDate];
    return time;
}


@end
